/**********************************************************************
 *                                                                    *
 * tgt - Tiny Graphics Toolbox                                        *
 *                                                                    *
 * Copyright (C) 2006-2008 Visualization and Computer Graphics Group, *
 * Department of Computer Science, University of Muenster, Germany.   *
 * <http://viscg.uni-muenster.de>                                     *
 *                                                                    *
 * This file is part of the tgt library. This library is free         *
 * software; you can redistribute it and/or modify it under the terms *
 * of the GNU Lesser General Public License version 2.1 as published  *
 * by the Free Software Foundation.                                   *
 *                                                                    *
 * This library is distributed in the hope that it will be useful,    *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the       *
 * GNU Lesser General Public License for more details.                *
 *                                                                    *
 * You should have received a copy of the GNU Lesser General Public   *
 * License in the file "LICENSE.txt" along with this library.         *
 * If not, see <http://www.gnu.org/licenses/>.                        *
 *                                                                    *
 **********************************************************************/

#include "tgt/navigation/trackball.h"

#include "tgt/quadric.h"
#include "tgt/toolkitfactory.h"
#include "tgt/guiapplication.h"
#include "tgt/painter.h"

using namespace tgt;

GUIApplication* tgtApp;
GLCanvas* glCanvas;

class MyPainter : public Painter {
public:
    virtual void paint();
    virtual void sizeChanged(const ivec2& size);
    virtual void init();
};

void MyPainter::paint() {

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    // set Camera
    getCamera()->look();

    Sphere sp(1., 32, 16);
    Quad qu(2., 2., 2.);
    Cylinder cy(.5, .2, 5., 16, 3);

    glColor3d(.8,.8,.8);
    sp.render();

    glColor3d(1.,0.,0.);
    glPushMatrix();
      glRotated(90.,1.,0.,0.);
      cy.render();
    glPopMatrix();

    glColor3d(0.,1.,0.);
    glPushMatrix();
      glRotated(90.,0.,1.,0.);
      cy.render();
    glPopMatrix();

    glColor3d(0.,0.,1.);
    glPushMatrix();
      glRotated(90.,0.,0.,1.);
      cy.render();
    glPopMatrix();

    glColor3d(1.,1.,0.);
    glPushMatrix();
      glTranslated(-1., 1., -1.);
      qu.render();
    glPopMatrix();
}

void MyPainter::sizeChanged(const ivec2& size) {
    glViewport(0,0,size.x,size.y);
    getCamera()->setRatio((float) size.x/size.y);
}

void MyPainter::init() {
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    getCamera()->positionCamera(vec3(0.f,0.f,10.f), vec3(0.f,0.f,0.f), vec3(0.f,1.f,0.f));
}

int main(int argc, char** argv) {

    std::cout 
        << "tgt Sample Program: trackballnavi" << std::endl
        << std::endl
        << "Demonstrate usage of tgt's trackball navigation." << std::endl
        << std::endl;
    
    std::cout
        << "Usage" << std::endl
        << "Drag-and-Drop with left mouse button, arrow keys" << std::endl
        << " ==> rotate the trackball" << std::endl
        << "SHIFT + Drag-and-Drop with left mouse button" << std::endl
        << " ==> move the trackball" << std::endl
        << "CTRL  + Drag-and-Drop with left mouse button, mouse wheel, PageUp-, PageDown-key" << std::endl
        << " ==> resize the trackball (zoom)" << std::endl
        << "SHIFT + mouse wheel" << std::endl
        << " ==> roll the trackball (tile camera)" << std::endl
        << std::endl;

    tgtApp = ToolkitFactory::createApplication(argc, argv);

    glCanvas = ToolkitFactory::createCanvas("tgt Example: Trackball");
    tgtApp->addCanvas(glCanvas);

    tgtApp->init();

    Camera camera;
    glCanvas->setCamera(&camera);
    MyPainter painter;
    glCanvas->setPainter(&painter);

    // make a trackball with standard mouse interaction
    Trackball trackball(glCanvas, true, ToolkitFactory::createTimer(glCanvas->getEventHandler()));

    // for a more simple trackball without continuous spinning feature, use
    //    Trackball trackball(glCanvas);
    // instead.

    // make sure trackball gets informed about events
    glCanvas->getEventHandler()->addListenerToFront(&trackball);

    // make trackball react on arrow keys as well (this is not default behavior)
    trackball.setKeyRotate();

    // make trackball zoom in and out on PageUp and PageDown keys (this is not default behavior)
    trackball.setKeyZoom(10.f, KeyEvent::K_PAGEUP, KeyEvent::K_PAGEDOWN, Event::NONE);

    // uncomment to try trackball with fixed center
    //trackball.setMoveCenter(false);

    tgtApp->run();

    delete glCanvas;
    delete tgtApp;

    return 0;
}
